perm filename APRL.FAI[REV,MUS] blob sn#350978 filedate 1978-04-27 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	TITLE APR - First-order all-pass reverberator, lattice form
C00005 00003	AC's
C00008 ENDMK
C⊗;
TITLE APR - First-order all-pass reverberator, lattice form

ENTRY APR
INTERNAL APR

COMMENT ⊗
EXTERNAL PROCEDURE APR(REFERENCE REAL IN, OUT; INTEGER n;
	REFERENCE REAL MEM; INTEGER delay;
	REAL gain; REFERENCE INTEGER pos);
Remarks:  Reverberates the samples in the input buffer "IN" into the
    output buffer "OUT", using the 1st order all-pass reverberator
    described by "gain" and "delay".  Delay line used is "MEM".
    For first call, "pos" should be set to 0 and "MEM" array should
    be filled with 0's.  On subsequent calls for the same input stream,
    the same "MEM" array and "pos" should be used (and not cleared to 0).
    The "IN" and "OUT" buffers may be the same array.  The buffer length
    "n" may even be 1, although that would be very inefficient.

Ex.:
DEFINE N=1000;
REAL ARRAY InStream,OutStream[1:N];
DEFINE Delay=23;
REAL ARRAY DelayMemory[1:Delay];
INTEGER SavedPointer;

Comment		First call:
	... fill InStream with samples here ...;
ARRCLR(DelayMemory);
APR(InStream[1],OutStream[1],N,DelayMemory[1],Delay,0.707,SavedPointer ← 0);
Comment		Subsequent calls:;
	... process OutStream samples here ...
	... fill InStream again here ...
APR(InStream[1],OutStream[1],N,DelayMemory[1],Delay,0.707,SavedPointer);

⊗;

;AC's
p←←17;		Usual PDL pointer
t←←0;		Temporary
i←←1;		Index for Input and Output arrays
j←←2;		Index for Delay memory

DEFINE refPOS <-1(p)>;	"Index" of current position in delay memory
DEFINE GAIN <-2(p)>;	Gain of attenuation loop
DEFINE DELAY <-3(p)>;	Number of samples of delay in loop
DEFINE refMEM <-4(p)>;	Address of first word of delay memory array
DEFINE N <-5(p)>;	Length of input and output buffers
DEFINE refOUT <-6(p)>;	Address of first word of output buffer array
DEFINE refIN <-7(p)>;	Address of first word of input buffer array
DEFINE nARGS <7>;
DEFINE SUBRET <
	SUB	p,[nARGS+1,,nARGS+1]
	JRST	@nARGS+1(p)
>

Apr:	MOVE	t,refIN;	Set up buffer processing loop for speed
	HRRM	t,In1
	HRRM	t,In2
	MOVE	t,refOUT
	HRRM	t,Out1
	MOVE	t,refMEM
	HRRM	t,Mem1
	HRRM	t,Mem2
	HRRM	t,Mem3
	MOVE	t,GAIN
	HLRM	t,Gain1
	MOVN	t,DELAY
	HRRM	t,Delay1
	SKIPN	j,@refPOS;	If POS is 0 then initialize it
	HRLZ	j,t
	MOVN	i,N
	HRLZ	i,i

Loop:			;These address fields are filled by code above
Mem1:	MOVE	t,(j);refMEM
In1:	FSBR	t,(i);refIN
Gain1:	FMPRI	t,;GAIN
Mem2:	FADRM	t,(j);refMEM
In2:	FADR	t,(i);refIN
Mem3:	EXCH	t,(j);refMEM
Out1:	MOVEM	t,(i);refOUT
	AOBJN	j,Testi
Delay1:	HRLZI	j,;DELAY
Testi:	AOBJN	i,Loop

	MOVEM	j,@refPOS
	SUBRET

	END